﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using TestesFixacao.Dominio.Modelos;
using TestesFixacao.Dominio.Readers;
using TestesFixacao.Dominio.Writers;
using TestesFixacao.Framework.Extensions;

namespace TestesFixacao.Dominio.Repositorios
{
    public class RepositorioMemoriaDisciplina : IRepositorioDisciplina, IRepositorioXml
    {
        private static readonly Dictionary<int, Disciplina> _disciplinas =
            new Dictionary<int, Disciplina>();

        public void Importa(string arquivo)
        {
            if (!File.Exists(arquivo))
                throw new FileNotFoundException("Arquivo não encontrado.");

            XmlTextReader readerRoot = new XmlTextReader(arquivo);

            AlternativaReader alternativaReader = new AlternativaReader();

            QuestaoReader questaoReader = new QuestaoReader(alternativaReader);

            DisciplinaReader disciplinaReader = new DisciplinaReader(questaoReader);

            List<Disciplina> disciplinas = new List<Disciplina>();

            disciplinaReader.Convert(readerRoot, disciplinas);

            foreach (var d in disciplinas)
            {
                _disciplinas.Add(d.Numero, d);
            }
        }

        public void ImportaUtilizandoLinq(string arquivo)
        {
            XDocument xmlDoc = XDocument.Load(arquivo);

            var disciplinas = (from d in xmlDoc.Descendants("serie")
                               select new Disciplina
                               {
                                   Nome = d.Element("nome").Value,
                                   Questoes = (from q in d.Descendants("alternativa")
                                               select new Questao
                                               {
                                                   Numero = int.Parse(q.Element("numero").Value),
                                                   Enunciado = q.Element("enunciado").Value,
                                                   Bimestre = int.Parse(q.Element("bimestre").Value),

                                                   Alternativas = (from a in q.Descendants("alternativa")
                                                                   select new Alternativa
                                                                   {
                                                                       Correta = bool.Parse(a.Element("correta").Value),
                                                                       Letra = char.Parse(a.Element("letra").Value),
                                                                       Resposta = a.Element("resposta").Value
                                                                   }).ToList()
                                               }).ToList()
                               }).ToList();

            var disciplinas1 = xmlDoc.Descendants("serie").Select(d => new Disciplina
                {
                    Nome = d.Element("nome").Value,

                    Questoes = d.Descendants("alternativa").Select(q => new Questao
                    {
                        Numero = int.Parse(q.Element("numero").Value),
                        Enunciado = q.Element("enunciado").Value,
                        Bimestre = int.Parse(q.Element("bimestre").Value),

                        Alternativas = q.Descendants("alternativa").Select(a => new Alternativa
                        {
                            Correta = bool.Parse(a.Element("correta").Value),
                            Letra = char.Parse(a.Element("letra").Value),
                            Resposta = a.Element("resposta").Value
                        }).ToList()
                    }).ToList(),
                }).ToList();
        }

        public void Exporta(string arquivo)
        {
            XmlTextWriter sw = new XmlTextWriter(arquivo, Encoding.UTF8);

            AlternativaWriter alternativaWriter = new AlternativaWriter();

            QuestaoWriter questaoWriter = new QuestaoWriter(alternativaWriter);

            DisciplinaWriter disciplinaWriter = new DisciplinaWriter(questaoWriter);

            var registros = _disciplinas.Values;

            disciplinaWriter.Convert(sw, registros.ToArray());

            sw.Close();
        }

        public void Adiciona(Disciplina d)
        {
            _disciplinas.Add(d.Numero, d);
        }

        public void Edita(Disciplina d)
        {
            _disciplinas[d.Numero] = d;
        }

        public Disciplina SelecionaPorId(int numero)
        {
            return _disciplinas[numero];
        }

        public List<Disciplina> SelecionaTodos()
        {
            return _disciplinas.Values.ToList();
        }

        public void Exclui(Disciplina obj)
        {
            _disciplinas.Remove(obj.Numero);
        }
    }
}